<template>
  <view class="fuzzy-search-container">
    <input
      v-model="searchKeyword"
      type="text"
      :placeholder="placeholder"
      @input="onSearchInput"
      @focus="onInputFocus"
      @blur="onInputBlur"
      class="search-input"
    />
    <view
      v-if="showSearchResults && filteredOptions.length > 0"
      class="search-results"
    >
      <view
        v-for="(item, index) in filteredOptions"
        :key="index"
        class="search-item"
        @click="selectItem(item)"
      >
        <text class="item-primary">{{ getFieldValue(item, displayField1) }}</text>
        <text v-if="displayField2 && getFieldValue(item, displayField2)" class="item-secondary">
          {{ getFieldValue(item, displayField2) }}
        </text>
      </view>
    </view>
    <view
      v-if="showSearchResults && filteredOptions.length === 0 && searchKeyword"
      class="search-results"
    >
      <view class="no-results">未找到相关内容</view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'FuzzySearch',
  props: {
    // 选项列表
    options: {
      type: Array,
      default: () => []
    },
    // 绑定字段（用于v-model）
    value: {
      type: [String, Number, Object],
      default: ''
    },
    // 显示内容1字段
    displayField1: {
      type: String,
      default: 'name'
    },
    // 显示内容2字段（可选）
    displayField2: {
      type: String,
      default: ''
    },
    // 选中取值字段
    valueField: {
      type: String,
      default: 'id'
    },
    // 搜索字段
    searchField: {
      type: String,
      default: 'name'
    },
    // 输入框占位符
    placeholder: {
      type: String,
      default: '请输入搜索内容'
    },
    // 是否区分大小写
    caseSensitive: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      searchKeyword: '',
      showSearchResults: false,
      filteredOptions: [],
      hasSelectedValidOption: false // 是否已选择有效选项
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(newVal) {
        if (newVal && typeof newVal === 'object') {
          this.searchKeyword = this.getFieldValue(newVal, this.displayField1) || '';
        } else if (newVal) {
          // 如果是简单值，尝试在options中找到对应的显示文本
          const item = this.options.find(option => option[this.valueField] === newVal);
          if (item) {
            this.searchKeyword = this.getFieldValue(item, this.displayField1) || '';
          }
        } else {
          // 外部清空绑定值时，同步清空显示文本
          this.searchKeyword = '';
        }
      }
    },
    options: {
      handler() {
        // 当选项变化，如果当前显示列表且没有关键字，保持展示全部
        if (this.showSearchResults && !this.searchKeyword) {
          this.filteredOptions = [...this.options];
        }
      },
      deep: true
    }
  },
  mounted() {
    this.addClickOutsideListener();
  },
  beforeDestroy() {
    this.removeClickOutsideListener();
  },
  methods: {
    // 获取嵌套字段值的方法
    getFieldValue(item, fieldPath) {
      if (!fieldPath || !item) return '';
      const fields = fieldPath.split('.');
      let value = item;
      for (const field of fields) {
        if (value && typeof value === 'object' && value[field] !== undefined) {
          value = value[field];
        } else {
          return '';
        }
      }
      return value;
    },

    // 搜索输入处理
    onSearchInput() {
      this.hasSelectedValidOption = false;
      if (!this.searchKeyword) {
        this.filteredOptions = [...this.options];
        this.showSearchResults = true;
        return;
      }
      this.filterOptions();
    },

    // 过滤选项
    filterOptions() {
      if (!this.searchKeyword) {
        this.filteredOptions = [];
        this.showSearchResults = false;
        return;
      }
      const keyword = this.caseSensitive ? this.searchKeyword : this.searchKeyword.toLowerCase();
      this.filteredOptions = this.options.filter(item => {
        const searchValue = this.getFieldValue(item, this.searchField);
        if (!searchValue) return false;
        const itemValue = this.caseSensitive ? searchValue : searchValue.toLowerCase();
        return itemValue.includes(keyword);
      });
      this.showSearchResults = true;
    },

    // 选择项目
    selectItem(item) {
      const value = item[this.valueField];
      this.searchKeyword = this.getFieldValue(item, this.displayField1);
      this.showSearchResults = false;
      this.hasSelectedValidOption = true;
      this.$emit('input', value);
      this.$emit('change', {
        value: value,
        item: item,
        label: this.getFieldValue(item, this.displayField1)
      });
    },

    // 处理输入框失焦
    onInputBlur() {
      setTimeout(() => {
        if (this.filteredOptions.length === 0 && this.searchKeyword && !this.hasSelectedValidOption) {
          this.searchKeyword = '';
          this.$emit('input', '');
          this.$emit('change', {});
        }
        this.showSearchResults = false;
      }, 150);
    },

    // 处理输入框聚焦
    onInputFocus() {
      this.showSearchResults = true;
      if (!this.searchKeyword) {
        this.filteredOptions = [...this.options];
      }
    },

    // 添加点击外部关闭搜索结果监听器
    addClickOutsideListener() {
      document.addEventListener('click', this.handleClickOutside);
    },

    // 移除点击外部监听器
    removeClickOutsideListener() {
      document.removeEventListener('click', this.handleClickOutside);
    },

    // 处理点击外部事件
    handleClickOutside(event) {
      const searchContainer = event.target?.closest('.fuzzy-search-container');
      if (!searchContainer) {
        this.showSearchResults = false;
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.fuzzy-search-container {
  position: relative;
  width: 100%;
  
  .search-input {
    width: 100%;
    font-size: 28rpx;
    background: #fff;
    
    &:focus {
      border-color: #1a66ff;
      outline: none;
    }
  }
  
  .search-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    border: 2rpx solid #e5e5e5;
    border-top: none;
    border-radius: 0 0 8rpx 8rpx;
    max-height: 500rpx;
    overflow-y: auto;
    z-index: 1000;
    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
    
    .search-item {
      padding: 20rpx;
      border-bottom: 1rpx solid #f0f0f0;
      cursor: pointer;
      
      &:hover {
        background: #f8f9fa;
      }
      
      &:last-child {
        border-bottom: none;
      }
      
      .item-primary {
        display: block;
        font-size: 28rpx;
        color: #666;
        margin-bottom: 8rpx;
        font-weight: 500;
      }
      
      .item-secondary {
        display: block;
        font-size: 24rpx;
        color: #999;
      }
    }
    
    .no-results {
      padding: 40rpx 20rpx;
      text-align: center;
      color: #999;
      font-size: 28rpx;
    }
  }
}
</style>
